import fs from "node:fs/promises";
import path from "node:path";
import { promisify } from "node:util";
import { execFile } from "node:child_process";
import { RunnerSpec, TaskHandler } from "../types";
import { resolvePath, ensureDir } from "../utils";

const execFileAsync = promisify(execFile);

async function runFigmaCli(spec: RunnerSpec, outputFile: string) {
  const cliPath = path.join(
    path.resolve(__dirname, "..", "..", ".."),
    "Figma-Context-MCP-DIY",
    "dist",
    "cli-fetch.js",
  );

  try {
    await fs.access(cliPath);
  } catch {
    throw new Error(
      "Figma CLI not found. Please build Workflow/Figma-Context-MCP-DIY (pnpm install && pnpm build).",
    );
  }

  const args = [cliPath, "--output-file", outputFile];

  if (spec.figma?.mainUrl) {
    args.push("--url", spec.figma.mainUrl);
  }
  if (spec.figma?.fileKey) {
    args.push("--file-key", spec.figma.fileKey);
  }
  if (spec.figma?.nodeId) {
    args.push("--node-id", spec.figma.nodeId);
  }

  await execFileAsync("node", args, {
    cwd: path.dirname(cliPath),
    env: process.env,
  });
}

export const figmaFetchRawTask: TaskHandler = async (spec, context) => {
  if (!spec.figma) {
    throw new Error("spec.figma is required for figma.fetchRaw");
  }

  const rawRelativePath =
    spec.figma.rawPath ?? spec.output?.raw ?? path.join(spec.output?.dir ?? "figma", "figma-main.yaml");
  const rawPath = resolvePath(rawRelativePath);
  await ensureDir(path.dirname(rawPath));

  if (spec.figma.fallback) {
    const fallbackPath = resolvePath(spec.figma.fallback);
    await fs.copyFile(fallbackPath, rawPath);
    return {
      summary: `Copied fallback data to ${rawRelativePath}`,
      outputPaths: { raw: rawRelativePath },
    };
  }

  if (!spec.figma.mainUrl && !spec.figma.fileKey) {
    throw new Error("Either figma.mainUrl, figma.fileKey, or figma.fallback must be provided");
  }

  await runFigmaCli(spec, rawPath);

  return {
    summary: `Fetched raw Figma data to ${rawRelativePath}`,
    outputPaths: { raw: rawRelativePath },
  };
};
